﻿package game.breeze.socket.server;

import game.breeze.socket.TcpSocket;
import game.breeze.socket.connection.NetConnection;
import game.breeze.socket.connection.SimpleConnection;
import game.breeze.socket.util.JobQueueOB;
import game.breeze.socket.util.NetJob;
import game.breeze.socket.util.Utils;

import java.net.Socket;
import java.util.ArrayList;


public class SimpleNetServer extends NetServer implements SocketConsumer, Runnable {
	private SocketFactory socketFactory;
	private ArrayList<SimpleConnection> connectionList = new ArrayList<SimpleConnection>();
	/**
	 * 接受新连接的时间，默认为100，即每秒最多接受10个连接请求
	 */
	private int acceptDelay = 100;

	public boolean start() {
		if (socketFactory == null) {
			try {
				socketFactory = new SocketFactory(getPort(), this);
			} catch (java.io.IOException e) {
				e.printStackTrace();
				return false;
			}
			socketFactory.start();
			new Thread(this, "SimpleNetServer").start();
		}
		return true;
	}

	public void stop() {
		try {
			socketFactory.stop();
			socketFactory = null;
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
	}

	public int getAcceptDelay() {
		return acceptDelay;
	}

	public void setAcceptDelay(int delay) {
		acceptDelay = delay;
	}

	public int getConnectionCount() {
		return connectionList.size();
	}

	public boolean acceptSocket() {
		if (getMaxConnections() > 0 && getMaxConnections() <= getConnectionCount()) {
			return false;
		}
		return true;
	}

	public void closeAllConnections() {
		SimpleConnection simpleConnection;
		for (int i = 0; i < connectionList.size(); i++) {
			simpleConnection = connectionList.get(i);
			if (simpleConnection != null && simpleConnection.isActive()) {
				simpleConnection.close();
			}
		}
		connectionList.clear();
	}

	public boolean consumeSocket(Socket socket) {
		if (!acceptSocket())
			return false;
		try {
			SimpleConnection connection = new SimpleConnection(new TcpSocket(socket));
			connectionOpened(connection);
			connectionList.add(connection);
			return true;
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public void run() {
		ArrayList<SimpleConnection> deletedList = new ArrayList<SimpleConnection>();
		long start = 0, time = 0;
		while (socketFactory != null) {
			start = System.currentTimeMillis();

			SimpleConnection simpleConnection;
			for (int i = 0; i < connectionList.size(); i++) {
				simpleConnection = connectionList.get(i);
				if (simpleConnection.isActive()) {
					JobQueueOB.getInstance().addJob(2, new ConnectionPeekJob(simpleConnection));
				} else {
					deletedList.add(simpleConnection);
				}
			}

			int count = deletedList.size();
			for (int i = 0; i < count; i++) {
				NetConnection conn = deletedList.get(i);
				connectionClosed(conn);
				connectionList.remove(conn);
			}
			deletedList.clear();
			time = System.currentTimeMillis() - start;
			if (time < 5)
				Utils.sleep(5);
		}
	}

	private class ConnectionPeekJob extends NetJob {
		private SimpleConnection simpleConnection;

		public ConnectionPeekJob(SimpleConnection simpleConnection) {
			this.simpleConnection = simpleConnection;
		}

		public NetConnection getConn() {
			return simpleConnection;
		}

		public void run() {
			simpleConnection.processPeek(System.currentTimeMillis());
		}
	}
}